package com.acando.feide;

import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import com.acando.feide.jaxb.EnterpriseType;
import com.acando.feide.utils.AppException;

public class FeideFileReader {

    /*
     * Read and unmarshal the contents of the file 'feide.xml'. Validate agaist schema 'schema\Feide.xsd'. Result is a
     * hierarchy of JAXB objects representing this content.
     */
    @SuppressWarnings("unchecked")
    public EnterpriseType doRead() throws AppException {

        JAXBContext jc;
        try {
            jc = JAXBContext.newInstance("com.acando.feide.jaxb");

            Unmarshaller u = jc.createUnmarshaller();

            SchemaFactory sf = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI);
            Schema schema = null;
            try {
                schema = sf.newSchema(new File("schema\\Feide.xsd"));
            } catch (SAXException se) {
                throw new AppException("Unable to validate schema. ", se);
            }
            u.setSchema(schema);
            u.setEventHandler(new ValidationEventHandler() {
                public boolean handleEvent(ValidationEvent ve) {
                    return false;
                }
            });

            JAXBElement<EnterpriseType> o = (JAXBElement<EnterpriseType>) u.unmarshal(new File("feide.xml"));
            return o.getValue();

        } catch (JAXBException je) {
            if (je.getLinkedException() != null && je.getLinkedException() instanceof SAXParseException) {
                SAXParseException spe = (SAXParseException) je.getLinkedException();
                throw new AppException("Schema validation error when parsing 'feide.xml'. Line:Col["
                        + spe.getLineNumber() + ":" + spe.getColumnNumber() + "]", spe);
            } else {
                throw new AppException("Problem reading intermidiate file 'feide.xml'.",
                        je.getLinkedException() == null ? je : je.getLinkedException());
            }
        }
    }
}
